
using System.Linq;
using Xunit;
using Xunit.Extensions;


namespace Boilen.Primitives.Members {

    public class TestMethodMember {

        [Fact]
        public void constructor_succeeds_for_null_body( ) {
            string name = "name";
            string type = "type";
            BlockMember nullBody = null;

            var mm = new MethodMember( name, type, nullBody );

            Assert.Null( mm.Body );
            Assert.True( mm.IsPartialMethod );
        }

        [Fact]
        public void constructor_succeeds_for_valid_arguments( ) {
            string name = "name";
            string type = "type";
            var body = new BlockMember( "block", w => { } );

            var mm = new MethodMember( name, type, body );

            Assert.Same( mm.Body, body );
            Assert.False( mm.IsPartialMethod );
        }


        [Fact]
        public void Write_succeeds_for_partial_method( ) {
            string name = "name";
            string type = "type";
            string[] expectedLines = new[] { "partial " + type + " " + name + "();", "" };
            BlockMember body = null;
            var mm = new MethodMember( name, type, body );
            var writer = new StringBuilderCodeWriter( );

            mm.Write( writer );

            string[] lines = writer.GetLines( );
            AssertExtensions.EqualCollection( lines, expectedLines );
        }

        [Fact]
        public void Write_succeeds_for_constructor( ) {
            string bodyName = ".ctor";
            string typeName = "type";
            BlockMember body = new BlockMember( bodyName, w => { } );
            var mm = new MethodMember( typeName, null, body );
            string[] expectedLines = new[] { mm.Modifiers + " " + typeName + "()", "{", "}", "" };
            var writer = new StringBuilderCodeWriter( );

            mm.Write( writer );

            string[] lines = writer.GetLines( );
            AssertExtensions.EqualCollection( lines, expectedLines );
        }

        [Theory]
        [InlineData( 0 )]
        [InlineData( 1 )]
        [InlineData( 3 )]
        public void Write_succeeds_for_valid_arguments( int parameterCount ) {
            string methodName = "MName";
            string methodType = "MType";
            string paramName = "name";
            string paramType = "type";
            var parameters = Enumerable.Range( 0, parameterCount )
                .Select( i => new ParameterMember( paramName + i, paramType ) )
                .ToArray( );
            string parameterString = Util.Join( parameters, ", ", ( i, p ) => p.Type + " " + p.Name );
            var emptyBody = new BlockMember( methodName + " body", _ => { } );
            var mm = new MethodMember( methodName, methodType, emptyBody );
            mm.Parameters.AddRange( parameters );
            string[] expectedLines = new[] {
                mm.Modifiers + " " + methodType + " " + methodName + "(" + parameterString + ")",
                "{",
                "}",
                ""
            };
            var writer = new StringBuilderCodeWriter( );

            mm.Write( writer );

            string[] lines = writer.GetLines( );
            AssertExtensions.EqualCollection( lines, expectedLines );
        }

    }

}
